/**
 * @brief link list
 * @author xiaoyao
 * @file linkls.c
 * @version V0.01
 */

/* ------------------------------------------------------------------------- */
#include "linkls.h"
/* ------------------------------------------------------------------------- */

#ifndef NULL
#define NULL 0
#endif

/**
 * @brief add newll to pll prev
 * @param pll list head to add it
 * @param newll new list
 */
int LinkLsAdd(struct linkls_s *pll, struct linkls_s *newll)
{

    if (pll == NULL)
    {
        return -1;
    }

    if (newll == NULL)
    {
        return -2;
    }

    newll->prev = pll->prev;
    newll->next = pll;

    pll->prev->next = newll;
    pll->prev = newll;

    return 0;
}

/**
 * @brief get node count of pll
 * @return count of pll
 */
int LinkLsGetItemCnt(struct linkls_s *pll)
{
    struct linkls_s *pnext = NULL;
    struct linkls_s *ptg = NULL;
    int count = 0;

    if (pll == NULL)
    {
        return -1;
    }

    ptg = pll;
    count++;

    while (1)
    {
        pnext = ptg->next;
        if (pnext == pll)
        {
            return count;
        }

        if (pnext == NULL)
        {
            return 0;
        }

        ptg = pnext;
        count++;
    }
}

/** 
 * @brief dell pll
 * @param pll list will del
 * @param pdll  del function
 * @return 
 */
int linklsDelAll(struct linkls_s *pll, void (*pdll)(struct linkls_s *))
{

    struct linkls_s *pnext = NULL;
    struct linkls_s *ptg = NULL;
    int count = 0;

    if (pll == NULL)
    {
        return -1;
    }

    if (pdll == NULL)
    {
        return -2;
    }

    ptg = pll;
    count++;

    while (1)
    {
        pnext = ptg->next;
        pdll(ptg);

        if (pnext == pll)
        {
            break;
        }

        if (pnext == NULL)
        {
            return -3;
        }

        ptg = pnext;
        count++;
    }

    return 0;
}
